﻿
//功能: 解析语法中的类型格式

//基本类型:
//utype uint8
//struct tanke
//前缀: [n],  utype*,  utype&

//复合类型:
//	[n]			utype uint8
//	utype*		utype uint8
//	utype&		utype uint8
//	[n]			struct tanke
//	utype*		struct tanke
//	utype&		struct tanke

//	utype* [n]	utype uint8
//	utype& [n]	utype uint8
//	[n] ram*	utype uint8
//	[n] ram&	utype uint8
//	utype* [n]	struct tanke
//	utype& [n]	struct tanke
//	[n] ram*	struct tanke
//	[n] ram&	struct tanke

namespace n_Parse
{
using System;
using n_ConstString;
using n_ET;
using n_ParseNet;
using n_UnitList;
using n_VdataList;
using n_WordList;
using n_VarList;
using n_MemberType;
using n_StructList;
using n_VarType;
using n_Struct;

public static class Parse
{
	public delegate void MemberListHandle( int Index );
	
	//用指定的成员列表函数处理源程序
	public static void DealWith( ref string UnitName, MemberListHandle handle )
	{
		UnitName = "";
		int Index = int.Parse( ParseNet.NodeSet[ ParseNet.Length - 1 ][ 1 ] );
		Unit( ref UnitName, Index, handle );
	}
	
	//解析元件定义
	public static void Unit( ref string UnitName, int Index, MemberListHandle handle )
	{
		int UnitNameIndex = 0;
		
		//处理重命名项
		int RenameIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		if( RenameIndex == -1 ) {
			UnitNameIndex = int.Parse( ParseNet.NodeSet[ Index ][ 4 ] );	
		}
		else {
			UnitNameIndex = int.Parse( ParseNet.NodeSet[ RenameIndex ][ 2 ] );
		}
		//合成当前所在的元件名
		if( UnitName == "" ) {
			//UnitName = WordList.GetWord( UnitNameIndex );
			UnitName = VarType.Root;
		}
		else {
			UnitName += "." + WordList.GetWord( UnitNameIndex );
		}
		//处理元件成员
		int MemberIndex = int.Parse( ParseNet.NodeSet[ Index ][ 6 ] );
		handle( MemberIndex );
		
		//退回元件级别
		int RemoveIndex = UnitName.LastIndexOf( '.' );
		if( RemoveIndex == -1 ) {
			UnitName = "";
		}
		else {
			UnitName = UnitName.Remove( RemoveIndex );
		}
	}
	
	//获取重命名项
	public static int GetRename( int Index, string UnitName, ref string VisitType, ref string RealRefType, ref string Name )
	{
		//读取访问类型
		int MemberTypeIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		Parse.GetMemberType( MemberTypeIndex, ref VisitType, ref RealRefType );
		
		//读取名称
		int NameIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		Name = UnitName + "." + WordList.GetWord( NameIndex );
		return NameIndex;
	}
	
	//获取成员类型
	public static void GetMemberType( int Index, ref string VisitType, ref string RealLinkType )
	{
		for( int i = 1; i < ParseNet.NodeSet[ Index ].Length; ++i ) {
			int TypeIndex = int.Parse( ParseNet.NodeSet[ Index ][ i ] );
			string Types = WordList.GetWord( TypeIndex );
			if( Types == MemberType.VisitType.Private || Types == MemberType.VisitType.Public ) {
				if( VisitType != null ) {
					ET.WriteParseError( TypeIndex, "此成员类型已经定义过: " + Types );
				}
				VisitType = Types;
			}
			if( Types == MemberType.RealRefType.link || Types == MemberType.RealRefType.Real ) {
				if( RealLinkType != null ) {
					ET.WriteParseError( TypeIndex, "此成员类型已经定义过: " + Types );
				}
				RealLinkType = Types;
			}
		}
		if( VisitType == null ) {
			VisitType = MemberType.VisitType.Private;
		}
		if( RealLinkType == null ) {
			RealLinkType = MemberType.RealRefType.Real;
		}
	}
	
	//获取最终成员名称
	public static void GetMemberNames( string BaseUnitName, int Index, ref string Name, ref int ErrorIndex )
	{
		string tBaseUnitName = BaseUnitName;
		int RootNameIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		if( RootNameIndex != -1 ) {
			BaseUnitName = VarType.Root;
		}
		Name = BaseUnitName;
		
		int NameIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		Name += "." + WordList.GetWord( NameIndex );
		
		int NextIndex = int.Parse( ParseNet.NodeSet[ Index ][ 3 ] );
		for( int i = 1; i < ParseNet.NodeSet[ NextIndex ].Length; ++i ) {
			NameIndex = int.Parse( ParseNet.NodeSet[ NextIndex ][ i ] );
			
			NameIndex = int.Parse( ParseNet.NodeSet[ NameIndex ][ 2 ] );
			Name += "." + WordList.GetWord( NameIndex );
		}
		ErrorIndex = NameIndex;
		
		if( Name == VarType.Root + "." + VarType.This ) {
			Name = tBaseUnitName;
		}
	}
	
	//获取变量类型
	public static string GetType( string BaseUnitName, int Index )
	{
		return GetMainType( BaseUnitName, Index, false );
	}
	
	//获取变量主体类型
	 static string GetMainType( string BaseUnitName, int Index, bool isComp )
	{
		string Type = null;
		bool isComplex = isComp;
		
		//获取扩展类型,即类型前缀
		int idx1 = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		if( idx1 != -1 ) {
			Type = GetExternMember( idx1, BaseUnitName );
			isComplex = true;
		}
		Index = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		
		//判断是否为结构体名称
		if( ParseNet.NodeSet[ Index ][ 0 ] == ParseNet.Node.结构体名称 ) {
			int ii = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
			int ErrorIndex = -1;
			string Name = null;
			Parse.GetMemberNames( BaseUnitName, ii, ref Name, ref ErrorIndex );
			int StructIndex = StructList.GetIndex( Name );
			if( StructIndex == -1 ) {
				ET.WriteParseError( ErrorIndex, "变量类型解析出错:未定义的结构体数据类型: " + Name );
				return null;
			}
			return Type + VarType.Struct + " " + StructList.Get( StructIndex ).Name;
		}
		//判断是否为结构体临时定义类型
		if( ParseNet.NodeSet[ Index ][ 0 ] == ParseNet.Node.结构体类型 ) {
			int NameIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
			int MemberIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
			int MemberNumber = ParseNet.NodeSet[ MemberIndex ].Length - 1;
			if( MemberNumber == 0 ) {
				ET.WriteParseError( NameIndex, "结构体的成员不能为空" );
				return null;
			}
			string StructName = Struct.AddNewStructAndCheck( MemberIndex, BaseUnitName );
			if( StructName == null ) {
				return null;
			}
			return Type + VarType.Struct + " " + StructName;
		}
		//判断是否为数组类型
		if( ParseNet.NodeSet[ Index ][ 0 ] == ParseNet.Node.数组类型 ) {
			
			int ii = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
			string ArrayMemberType = GetMainType( BaseUnitName, ii, true );
			
			int WordIndex = int.Parse( ParseNet.NodeSet[ Index ][ 4 ] );
			
			//获取数组长度
			string Length = null;
			if( ParseNet.NodeSet[ WordIndex ][ 0 ] != ParseNet.Node.终结词 ||
			    WordList.GetWord( WordIndex ) != "?" ) {
				Length = ConstExpression.GetExpressionValue( WordIndex, BaseUnitName );
			}
			return Type + VarType.Array + Length + " " + ArrayMemberType;
		}
		//判断是否为新版数组类型
		if( ParseNet.NodeSet[ Index ][ 0 ] == ParseNet.Node.新版数组类型 ) {
			
			int ii = int.Parse( ParseNet.NodeSet[ Index ][ 4 ] );
			string ArrayMemberType = GetMainType( BaseUnitName, ii, true );
			
			int WordIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
			
			//获取数组长度
			string Length = null;
			if( WordIndex != -1 ) {
				Length = ConstExpression.GetExpressionValue( WordIndex, BaseUnitName );
			}
			return Type + VarType.Array + Length + " " + ArrayMemberType;
		}
		//到这里说明是 @普通变量基本类型
		int idx2 = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		int idx3 = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		string BaseType = WordList.GetWord( idx3 );
		
		//如果不是默认元件类型,获取元件名
		if( idx2 != -1 ) {
			string VdataType = null;
			int LastIndex = 0;
			GetMemberNames( BaseUnitName, idx2, ref VdataType, ref LastIndex );
			int VdataIndex = VdataList.GetIndex( VdataType );
			if( VdataIndex == -1 ) {
				ET.WriteParseError( LastIndex, "变量类型解析出错:未定义的虚拟数据类型: " + VdataType );
				return null;
			}
			Type += VdataList.Get( VdataIndex ).VdataName + " " + BaseType;
		}
		//到这里说明是默认的元件类型
		else {
			if( isComplex ) {
				Type += VarType.VBase + " " + BaseType;
			}
			else {
				Type += BaseType;
			}
		}
		return Type;
	}
	
	//获取类型前缀
	static string GetExternMember( int Index, string BaseUnitName )
	{
		int VdataTypeIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		
		//获取存储类型
		string VdataType = null;
		if( VdataTypeIndex == -1 ) {
			
			//2013.3.15
			//注意这里不需要添加基本类型,和这个地方对应的是 Expression.cs中的 引用运算
			
			//2013.3.20
			//又加上了...
			
			VdataType = VarType.VBase;
		}
		else {
			int ErrorIndex = -1;
			Parse.GetMemberNames( BaseUnitName, VdataTypeIndex, ref VdataType, ref ErrorIndex );
			if( VdataList.GetIndex( VdataType ) == -1 ) {
				ET.WriteParseError( int.Parse( ParseNet.NodeSet[ Index ][ 2 ] ), "解析变量类型时发现未定义的元件类型: " + VdataType );
				return null;
			}
		}
		int i = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		if( ParseNet.NodeSet[ i ][ 0 ] == ParseNet.Node.引用前缀符号 ) {
			return VdataType + VarType.Refer + " ";
		}
		else {
			return VdataType + VarType.Pointer + " ";
		}
	}
}
}




